import { Window_Selectable } from "@/windows/Window_Selectable.js";
import { config } from "@/managers/ConfigManager.js";
import { SoundManager } from "@/managers/SoundManager.js";
import { clamp } from "@/utils/number.js";
import { Input } from "@/core/Input.js";
import { TouchInput } from "@/core/TouchInput.js";

import { Sprite_Button } from "@/sprites/Sprite_Button.js";
import { ImageManager } from "@/managers/ImageManager.js";


export class Window_NumberInput extends Window_Selectable {
    constructor(messageWindow) {
        super(0, 0, 0, 0);
        this._messageWindow = messageWindow;
        this._number = 0;
        this._maxDigits = 1;
        this.createButtons();
        this.deactivate();
    }

    start() {
        this._maxDigits = $gameMessage.numInputMaxDigits();
        this._number = $gameVariables.value($gameMessage.numInputVariableId());
        this._number = clamp(this._number,0, Math.pow(10, this._maxDigits) - 1);
        this.updatePlacement();
        this.placeButtons();
        this.updateButtonsVisiblity();
        this.createContents();
        this.refresh();
        this.open();
        this.activate();
        this.select(0);
    }

    updatePlacement() {
        let messageY = this._messageWindow.y;
        let spacing = 8;
        let width = this.windowWidth();
        let height = this.windowHeight();
        this.x = (config.width - width) / 2;
        if (messageY >= config.height / 2) {
            this.y = messageY - height - spacing;
        } else {
            this.y = messageY + this._messageWindow.height + spacing;
        }
    }

    windowWidth() {
        return this.maxCols() * this.itemWidth() + this.padding * 2;
    }

    windowHeight() {
        return this.fittingHeight(1);
    }

    maxCols() {
        return this._maxDigits;
    }

    maxItems() {
        return this._maxDigits;
    }

    spacing() {
        return 0;
    }

    itemWidth() {
        return 32;
    }

    createButtons() {
        ImageManager.loadSystem('ButtonSet').then(source=>{
            let buttonWidth = 48;
            let buttonHeight = 48;
            this._buttons = [];

            source.refCount+=2;

            for (let i = 0; i < 3; i++) {
                let button = new Sprite_Button(source);
                let x = buttonWidth * [1, 2, 4][i];
                let w = buttonWidth * (i === 2 ? 2 : 1);
                button.setColdFrame(x, 0, w, buttonHeight);
                button.setHotFrame(x, buttonHeight, w, buttonHeight);
                button.visible = false;
                this._buttons.push(button);
                this.addChild(button);
            }
            this._buttons[0].setClickHandler(this.onButtonDown.bind(this));
            this._buttons[1].setClickHandler(this.onButtonUp.bind(this));
            this._buttons[2].setClickHandler(this.onButtonOk.bind(this));
        });
        
    }

    placeButtons() {
        let numButtons = this._buttons.length;
        let spacing = 16;
        let totalWidth = -spacing;
        for (let i = 0; i < numButtons; i++) {
            totalWidth += this._buttons[i].width + spacing;
        }
        let x = (this.width - totalWidth) / 2;
        for (let j = 0; j < numButtons; j++) {
            let button = this._buttons[j];
            button.x = x;
            button.y = this.buttonY();
            x += button.width + spacing;
        }
    }

    updateButtonsVisiblity() {
        if (TouchInput.date > Input.date) {
            this.showButtons();
        } else {
            this.hideButtons();
        }
    }

    showButtons() {
        for (let i = 0; i < this._buttons.length; i++) {
            this._buttons[i].visible = true;
        }
    }

    hideButtons() {
        for (let i = 0; i < this._buttons.length; i++) {
            this._buttons[i].visible = false;
        }
    }

    buttonY() {
        let spacing = 8;
        if (this._messageWindow.y >= config.height / 2) {
            return 0 - this._buttons[0].height - spacing;
        } else {
            return this.height + spacing;
        }
    }

    update() {
        super.update();
        this.processDigitChange();
    }

    processDigitChange() {
        if (this.isOpenAndActive()) {
            if (Input.isRepeated('up')) {
                this.changeDigit(true);
            } else if (Input.isRepeated('down')) {
                this.changeDigit(false);
            }
        }
    }

    changeDigit(up) {
        let index = this.index();
        let place = Math.pow(10, this._maxDigits - 1 - index);
        let n = Math.floor(this._number / place) % 10;
        this._number -= n * place;
        if (up) {
            n = (n + 1) % 10;
        } else {
            n = (n + 9) % 10;
        }
        this._number += n * place;
        this.refresh();
        SoundManager.playCursor();
    }

    isTouchOkEnabled() {
        return false;
    }

    isOkEnabled() {
        return true;
    }

    isCancelEnabled() {
        return false;
    }

    isOkTriggered() {
        return Input.isTriggered('ok');
    }

    processOk() {
        SoundManager.playOk();
        $gameVariables.setValue($gameMessage.numInputVariableId(), this._number);
        this._messageWindow.terminateMessage();
        this.updateInputData();
        this.deactivate();
        this.close();
    }

    drawItem(index) {
        let rect = this.itemRect(index);
        let align = 'center';
        let s = String(this._number).padStart(this._maxDigits,'0');
        let c = s.slice(index, index + 1);
        this.resetTextColor();
        this.drawText(c, rect.x, rect.y, rect.width, align);
    }

    onButtonUp() {
        this.changeDigit(true);
    }

    onButtonDown() {
        this.changeDigit(false);
    }

    onButtonOk() {
        this.processOk();
        this.hideButtons();
    }
}